home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_2.2 / HISTEX / HISTEX.C < prev    next >
C/C++ Source or Header  |  1999-09-11  |  6KB  |  190 lines

  1. /* 
  2.  * histstats.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* HISTEX: program performs histogram expansion upon a b/w image - removing
  10.  *       the tails of the probability density function and expanding that 
  11.  *         function to the entire range, where <hiValue> is the max intensity
  12.  *              usage: histex inimg outimg [-p PCT_KEEP] [-m MAXVAL] [-L]
  13.  *
  14.  *
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <tiffimage.h>          /* tiff info on images */
  21. #include <images.h>
  22. extern void print_sos_lic ();
  23.  
  24. #define NBINS 256               /* no. of histogram bins */
  25. #define PCT_KEEP 98.0           /* percentage of histogram to keep */
  26.  
  27. int usage (short);
  28. int input (int, char **, double *, long *);
  29. int histogram (char *, int, int *);
  30.  
  31. main (argc, argv)
  32.      int argc;
  33.      char *argv[];
  34. {
  35.   Image *imgI;                  /* I/O image structure */
  36.   unsigned char **image;        /* input/output image */
  37.   double pctKeep;               /* percent of histogram to keep */
  38.   double tail,                  /* percent of histogram tail to remove */
  39.     expand,                     /* factor for histogram expansion */
  40.     value;                      /* pixel value after hist. expansion */
  41.   long nTotal,                  /* total no. of elements in image */
  42.     hiValue,                    /* high intensity value */
  43.     nRemove,                    /* no. pixels to remove in hist. tail */
  44.     sum,                        /* running sum of pixels in tail */
  45.     shift,                      /* shift (down to zero) for hist. exp. */
  46.     top,                        /* top value for expansion */
  47.     i, j;
  48.   int hist[NBINS];              /* image histogram array */
  49.  
  50.   struct point imgSize;         /* image dimensions */
  51.  
  52. /* read user parameter values */
  53.   if ((input (argc, argv, &pctKeep, &hiValue)) < 0)
  54.     return (-1);
  55.   tail = (100.0 - pctKeep) / 2.0;
  56.  
  57. /* open image */
  58.   imgI = ImageIn (argv[1]);
  59.   if (imgI->bps == 8 && imgI->spp == 3) {
  60.     printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
  61.     exit (1);
  62.   }
  63.   image = imgI->img;
  64.   imgSize.y = ImageGetHeight (imgI);
  65.   imgSize.x = ImageGetWidth (imgI);
  66.   printf ("image size is %dx%d\n", imgSize.x, imgSize.y);
  67.  
  68. /* zero histogram array */
  69.   for (i = 0; i < NBINS; i++)
  70.     hist[i] = 0;
  71.  
  72. /* construct histogram */
  73.   for (j = 0, nTotal = 0; j < imgSize.y; j++) {
  74.     nTotal += imgSize.x;
  75.     histogram (image[j], imgSize.x, hist);
  76.   }
  77.   nRemove = (int) (nTotal * tail / 100.0);
  78.  
  79. /* find lower tail */
  80.   for (i = 0, sum = 0; i < NBINS; i++) {
  81.     sum += hist[i];
  82.     if (sum >= nRemove)
  83.       break;
  84.   }
  85.   shift = i;
  86.  
  87. /* find upper tail */
  88.   for (i = NBINS - 1, sum = 0; i > 0; --i) {
  89.     sum += hist[i];
  90.     if (sum >= nRemove)
  91.       break;
  92.   }
  93.   top = i;
  94.   expand = (double) (hiValue) / (double) (top - shift + 1);
  95.  
  96.   printf ("Tails: %d, %d. Histogram expansion = %5.2f.\n",
  97.           shift, top, expand);
  98.  
  99. /* do histogram expansion on input data and write output */
  100.   for (j = 0; j < imgSize.y; j++) {
  101.     for (i = 0; i < imgSize.x; i++) {
  102.       value = (((double) image[j][i]) - shift) * expand;
  103.       if (value < 0.0)
  104.         value = 0.0;
  105.       else if (value > hiValue)
  106.         value = hiValue;
  107.       image[j][i] = (unsigned char) value;
  108.     }
  109.   }
  110.   ImageOut (argv[2], imgI);
  111.   return (0);
  112. }
  113.  
  114. /* USAGE:       function gives instructions on usage of program
  115.  *                    usage: usage (flag)
  116.  *              When flag is 1, the long message is given, 0 gives short.
  117.  */
  118.  
  119. int
  120. usage (flag)
  121.      short flag;                /* flag =1 for long message; =0 for short message */
  122. {
  123.  
  124. /* print short usage message or long */
  125.   printf ("USAGE: histex inimg outimg [-p PCT_KEEP] [-m MAXVAL] [-L]\n");
  126.   if (flag == 0)
  127.     return (-1);
  128.  
  129.   printf ("\nhistex enhances image contrast by performing\n");
  130.   printf ("histogram expansion.\n\n");
  131.   printf ("ARGUMENTS:\n");
  132.   printf ("    inimg: input image filename (TIF)\n");
  133.   printf ("   outimg: output image filename (TIF)\n\n");
  134.   printf ("OPTIONS:\n");
  135.   printf ("  -p PCT_KEEP: percent of histogram to keep. Tails at upper\n");
  136.   printf ("               and lower of histogram are removed equally.\n");
  137.   printf ("               (default = %d%%)\n", (long) PCT_KEEP);
  138.   printf ("  -m MAXVALUE: maximum value of image intensity (if different\n");
  139.   printf ("               than 255), default = %d\n", NBINS - 1);
  140.   printf ("           -L: print Software License for this module\n");
  141.  
  142.   return (-1);
  143. }
  144.  
  145.  
  146. /* INPUT:       function reads input parameters
  147.  *                  usage: input (argc, argv, pctKeep, hiValue)
  148.  */
  149.  
  150. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  151.  
  152. int
  153. input (argc, argv, pctKeep, hiValue)
  154.      int argc;
  155.      char *argv[];
  156.      double *pctKeep;           /* percentage of histogram to keep */
  157.      long *hiValue;             /* maximum output intensity value */
  158. {
  159.   long n;
  160.  
  161.   if (argc == 1)
  162.     USAGE_EXIT (1);
  163.   if (argc == 2)
  164.     USAGE_EXIT (0);
  165.  
  166.   *pctKeep = PCT_KEEP;
  167.   *hiValue = NBINS - 1;
  168.  
  169.   for (n = 3; n < argc; n++) {
  170.     if (strcmp (argv[n], "-p") == 0) {
  171.       if (++n == argc || argv[n][0] == '-')
  172.         USAGE_EXIT (0);
  173.       *pctKeep = (double) atol (argv[n]);
  174.     }
  175.     else if (strcmp (argv[n], "-m") == 0) {
  176.       if (++n == argc || argv[n][0] == '-')
  177.         USAGE_EXIT (0);
  178.       *hiValue = atol (argv[n]);
  179.     }
  180.     else if (strcmp (argv[n], "-L") == 0) {
  181.       print_sos_lic ();
  182.       exit (0);
  183.     }
  184.     else
  185.       USAGE_EXIT (0);
  186.   }
  187.  
  188.   return (0);
  189. }
  190.